home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char Rcs_Id[] =
- "$Id: ispell.c 1.131 1995/01/08 23:23:39 geoff Exp $";
- #endif
-
- #define MAIN
-
- /*
- * ispell.c - An interactive spelling corrector.
- *
- * Copyright (c), 1983, by Pace Willisson
- *
- * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All modifications to the source code must be clearly marked as
- * such. Binary redistributions based on modified source code
- * must be clearly marked as modified versions in the documentation
- * and/or other materials provided with the distribution.
- * 4. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by Geoff Kuenning and
- * other unpaid contributors.
- * 5. The name of Geoff Kuenning may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- /*
- * $Log: ispell.c $
- * Revision 1.131 1995/01/08 23:23:39 geoff
- * Support variable hashfile suffixes for DOS purposes. Report all the
- * new configuration variables in the -vv switch. Do some better error
- * checking for mktemp failures. Support the rename system call. All of
- * this is to help make DOS porting easier.
- *
- * Revision 1.130 1995/01/03 19:24:08 geoff
- * When constructing a personal-dictioary name from the hash file name,
- * don't stupidly include path directory components.
- *
- * Revision 1.129 1995/01/03 02:23:19 geoff
- * Disable the setbuf call on BSDI systems, sigh.
- *
- * Revision 1.128 1994/10/26 05:12:28 geoff
- * Include boundary characters in the list of characters to be tried in
- * corrections.
- *
- * Revision 1.127 1994/10/25 05:46:07 geoff
- * Allow the default dictionary to be specified by an environment
- * variable (DICTIONARY) as well as a switch.
- *
- * Revision 1.126 1994/09/16 03:32:34 geoff
- * Issue an error message for bad affix flags
- *
- * Revision 1.125 1994/07/28 05:11:36 geoff
- * Log message for previous revision: fix backup-file checks to correctly
- * test for exceeding MAXNAMLEN.
- *
- * Revision 1.124 1994/07/28 04:53:39 geoff
- *
- * Revision 1.123 1994/05/17 06:44:12 geoff
- * Add support for controlled compound formation and the COMPOUNDONLY
- * option to affix flags.
- *
- * Revision 1.122 1994/04/27 01:50:37 geoff
- * Print MAX_CAPS in -vv mode.
- *
- * Revision 1.121 1994/03/16 03:49:10 geoff
- * Fix -vv to display the value of NO_STDLIB_H.
- *
- * Revision 1.120 1994/03/15 06:24:28 geoff
- * Allow the -t, -n, and -T switches to override each other, as follows:
- * if no switches are given, the deformatter and string characters are
- * chosen based on the file suffix. If only -t/-n are given, the
- * deformatter is forced but string cahracters come from the file suffix.
- * If only -T is given, the deformatter is chosen based on the value
- * given in the -T switch. Finally, if both -T and -t/-n are given,
- * string characters are controlled by -T and the deformatter by -t/-n.
- *
- * Revision 1.119 1994/03/15 05:58:07 geoff
- * Get rid of a gcc warning
- *
- * Revision 1.118 1994/03/15 05:30:37 geoff
- * Get rid of an unused-variable complaint by proper ifdeffing
- *
- * Revision 1.117 1994/03/12 21:26:48 geoff
- * Correctly limit maximum name lengths for files that have directory paths
- * included. Also don't use a wired-in 256 for the size of the backup file
- * name.
- *
- * Revision 1.116 1994/02/07 08:10:44 geoff
- * Print GENERATE_LIBRARY_PROTOS in the -vv switch.
- *
- * Revision 1.115 1994/01/26 07:44:47 geoff
- * Make yacc configurable through local.h.
- *
- * Revision 1.114 1994/01/25 07:11:44 geoff
- * Get rid of all old RCS log lines in preparation for the 3.1 release.
- *
- */
-
- #include "config.h"
- #include "ispell.h"
- #include "proto.h"
- #include "msgs.h"
-
- #ifdef AMIGA
- extern char * Version_ID[];
- #else
- #include "version.h"
- #endif
-
- #include <ctype.h>
- #include <sys/stat.h>
-
- static void usage P ((void));
- static void initckch P ((char * wchars));
- int main P ((int argc, char * argv[]));
- static void dofile P ((char * filename));
- static void update_file P ((char * filename, struct stat * statbuf));
- static void expandmode P ((int printorig));
-
- static char * Cmd;
- static char * LibDict = NULL; /* Pointer to name of $(LIBDIR)/dict */
-
- static void usage ()
- {
-
- (void) fprintf (stderr, ISPELL_C_USAGE1, Cmd);
- (void) fprintf (stderr, ISPELL_C_USAGE2, Cmd);
- (void) fprintf (stderr, ISPELL_C_USAGE3, Cmd);
- #ifdef AMIGA
- (void) fprintf (stderr, " %s [-dfile | -pfile | -ffile | -Wn | -t | -n | -s | -B | -C | -P | -m | -Ttype] -r\n", Cmd);
- #endif
- (void) fprintf (stderr, ISPELL_C_USAGE4, Cmd);
- (void) fprintf (stderr, ISPELL_C_USAGE5, Cmd);
- (void) fprintf (stderr, ISPELL_C_USAGE6, Cmd);
- (void) fprintf (stderr, ISPELL_C_USAGE7, Cmd);
- givehelp (0);
- exit (1);
- }
-
- static void initckch (wchars)
- char * wchars; /* Characters in -w option, if any */
- {
- register ichar_t c;
- char num[4];
-
- for (c = 0; c < (ichar_t) (SET_SIZE + hashheader.nstrchars); ++c)
- {
- if (iswordch (c))
- {
- if (!mylower (c))
- {
- Try[Trynum] = c;
- ++Trynum;
- }
- }
- else if (isboundarych (c))
- {
- Try[Trynum] = c;
- ++Trynum;
- }
- }
- if (wchars != NULL)
- {
- while (Trynum < SET_SIZE && *wchars != '\0')
- {
- if (*wchars != 'n' && *wchars != '\\')
- {
- c = *wchars;
- ++wchars;
- }
- else
- {
- ++wchars;
- num[0] = '\0';
- num[1] = '\0';
- num[2] = '\0';
- num[3] = '\0';
- if (isdigit (wchars[0]))
- {
- num[0] = wchars[0];
- if (isdigit (wchars[1]))
- {
- num[1] = wchars[1];
- if (isdigit (wchars[2]))
- num[2] = wchars[2];
- }
- }
- if (wchars[-1] == 'n')
- {
- wchars += strlen (num);
- c = atoi (num);
- }
- else
- {
- wchars += strlen (num);
- c = 0;
- if (num[0])
- c = num[0] - '0';
- if (num[1])
- {
- c <<= 3;
- c += num[1] - '0';
- }
- if (num[2])
- {
- c <<= 3;
- c += num[2] - '0';
- }
- }
- }
- c &= NOPARITY;
- if (!hashheader.wordchars[c])
- {
- hashheader.wordchars[c] = 1;
- hashheader.sortorder[c] = hashheader.sortval++;
- Try[Trynum] = c;
- ++Trynum;
- }
- }
- }
- }
-
- int main (argc, argv)
- int argc;
- char * argv[];
- {
- char * p;
- char * cpd;
- char ** versionp;
- char * wchars = NULL;
- char * preftype = NULL;
- static char libdictname[sizeof DEFHASH];
- static char outbuf[BUFSIZ];
- int argno;
- int arglen;
-
- Cmd = *argv;
-
- Trynum = 0;
-
- p = getenv ("DICTIONARY");
- if (p != NULL)
- {
- #ifdef AMIGA
- if ((index (p, '/') != NULL) || (index (p, ':') != NULL))
- #else
- if (index (p, '/') != NULL)
- #endif
- (void) strcpy (hashname, p);
- else
- (void) sprintf (hashname, "%s/%s", LIBDIR, p);
- p = rindex (p, '.');
- if (p == NULL || strcmp (p, HASHSUFFIX) != 0)
- (void) strcat (hashname, HASHSUFFIX);
- }
- else
- (void) sprintf (hashname, "%s/%s", LIBDIR, DEFHASH);
-
- cpd = NULL;
-
- argv++;
- argc--;
- while (argc && **argv == '-')
- {
- /*
- * Trying to add a new flag? Can't remember what's been used?
- * Here's a handy guide:
- *
- * Used:
- *
- * ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
- * ^^^^ ^^^ ^ ^^ ^^
- * abcdefghijklmnopqrstuvwxyz
- * ^^^^^^ ^^^ ^ ^^^ ^^^
- */
- arglen = strlen (*argv);
- switch ((*argv)[1])
- {
- case 'v':
- if (arglen > 3)
- usage ();
- for (versionp = Version_ID; *versionp; )
- {
- p = *versionp++;
- if (strncmp (p, "(#) ", 5) == 0)
- p += 5;
- (void) printf ("%s\n", p);
- }
-
- #ifndef AMIGA
- if ((*argv)[2] == 'v')
- {
- (void) printf (ISPELL_C_OPTIONS_ARE);
- #ifdef USG
- (void) printf ("\tUSG\n");
- #else /* USG */
- (void) printf ("\t!USG (BSD)\n");
- #endif /* USG */
- (void) printf ("\tBAKEXT = \"%s\"\n", BAKEXT);
- (void) printf ("\tBINDIR = \"%s\"\n", BINDIR);
- #ifdef BOTTOMCONTEXT
- (void) printf ("\tBOTTOMCONTEXT\n");
- #else /* BOTTOMCONTEXT */
- (void) printf ("\t!BOTTOMCONTEXT\n");
- #endif /* BOTTOMCONTEXT */
- #if TERM_MODE == CBREAK
- (void) printf ("\tCBREAK\n");
- #endif /* TERM_MODE */
- (void) printf ("\tCC = \"%s\"\n", CC);
- (void) printf ("\tCFLAGS = \"%s\"\n", CFLAGS);
- #ifdef COMMANDFORSPACE
- (void) printf ("\tCOMMANDFORSPACE\n");
- #else /* COMMANDFORSPACE */
- (void) printf ("\t!COMMANDFORSPACE\n");
- #endif /* COMMANDFORSPACE */
- #ifdef CONTEXTROUNDUP
- (void) printf ("\tCONTEXTROUNDUP\n");
- #else /* CONTEXTROUNDUP */
- (void) printf ("\t!CONTEXTROUNDUP\n");
- #endif /* CONTEXTROUNDUP */
- (void) printf ("\tCONTEXTPCT = %d\n", CONTEXTPCT);
- (void) printf ("\tCOUNTSUFFIX = \"%s\"\n", COUNTSUFFIX);
- (void) printf ("\tDEFHASH = \"%s\"\n", DEFHASH);
- (void) printf ("\tDEFINCSTR = \"%s\"\n", DEFINCSTR);
- (void) printf ("\tDEFLANG = \"%s\"\n", DEFLANG);
- (void) printf ("\tDEFNOBACKUPFLAG = %d\n",
- DEFNOBACKUPFLAG);
- (void) printf ("\tDEFPAFF = \"%s\"\n", DEFPAFF);
- (void) printf ("\tDEFPDICT = \"%s\"\n", DEFPDICT);
- (void) printf ("\tDEFTEXFLAG = %d\n", DEFTEXFLAG);
- (void) printf ("\tEGREPCMD = \"%s\"\n", EGREPCMD);
- (void) printf ("\tELISPDIR = \"%s\"\n", ELISPDIR);
- (void) printf ("\tEMACS = \"%s\"\n", EMACS);
- #ifdef EQUAL_COLUMNS
- (void) printf ("\tEQUAL_COLUMNS\n");
- #else /* EQUAL_COLUMNS */
- (void) printf ("\t!EQUAL_COLUMNS\n");
- #endif /* EQUAL_COLUMNS */
- #ifdef GENERATE_LIBRARY_PROTOS
- (void) printf ("\tGENERATE_LIBRARY_PROTOS\n");
- #else /* GENERATE_LIBRARY_PROTOS */
- (void) printf ("\t!GENERATE_LIBRARY_PROTOS\n");
- #endif /* GENERATE_LIBRARY_PROTOS */
- #ifdef HAS_RENAME
- (void) printf ("\tHAS_RENAME\n");
- #else /* HAS_RENAME */
- (void) printf ("\t!HAS_RENAME\n");
- #endif /* HAS_RENAME */
- (void) printf ("\tHASHSUFFIX = \"%s\"\n", HASHSUFFIX);
- (void) printf ("\tHOME = \"%s\"\n", HOME);
- #ifdef IGNOREBIB
- (void) printf ("\tIGNOREBIB\n");
- #else /* IGNOREBIB */
- (void) printf ("\t!IGNOREBIB\n");
- #endif /* IGNOREBIB */
- (void) printf ("\tINCSTRVAR = \"%s\"\n", INCSTRVAR);
- (void) printf ("\tINPUTWORDLEN = %d\n", INPUTWORDLEN);
- (void) printf ("\tLANGUAGES = \"%s\"\n", LANGUAGES);
- (void) printf ("\tLIBDIR = \"%s\"\n", LIBDIR);
- (void) printf ("\tLIBES = \"%s\"\n", LIBES);
- (void) printf ("\tLINT = \"%s\"\n", LINT);
- (void) printf ("\tLINTFLAGS = \"%s\"\n", LINTFLAGS);
- #ifndef REGEX_LOOKUP
- (void) printf ("\tLOOK = \"%s\"\n", LOOK);
- #endif /* REGEX_LOOKUP */
- (void) printf ("\tMAKE_SORTTMP = \"%s\"\n", MAKE_SORTTMP);
- (void) printf ("\tMALLOC_INCREMENT = %d\n",
- MALLOC_INCREMENT);
- (void) printf ("\tMAN1DIR = \"%s\"\n", MAN1DIR);
- (void) printf ("\tMAN1EXT = \"%s\"\n", MAN1EXT);
- (void) printf ("\tMAN4DIR = \"%s\"\n", MAN4DIR);
- (void) printf ("\tMAN4EXT = \"%s\"\n", MAN4EXT);
- (void) printf ("\tMASKBITS = %d\n", MASKBITS);
- (void) printf ("\tMASKTYPE = %s\n", MASKTYPE_STRING);
- (void) printf ("\tMASKTYPE_WIDTH = %d\n", MASKTYPE_WIDTH);
- (void) printf ("\tMASTERHASH = \"%s\"\n", MASTERHASH);
- (void) printf ("\tMAXAFFIXLEN = %d\n", MAXAFFIXLEN);
- (void) printf ("\tMAXCONTEXT = %d\n", MAXCONTEXT);
- (void) printf ("\tMAXINCLUDEFILES = %d\n",
- MAXINCLUDEFILES);
- (void) printf ("\tMAXNAMLEN = %d\n", MAXNAMLEN);
- (void) printf ("\tMAXPATHLEN = %d\n", MAXPATHLEN);
- (void) printf ("\tMAXPCT = %d\n", MAXPCT);
- (void) printf ("\tMAXSEARCH = %d\n", MAXSEARCH);
- (void) printf ("\tMAXSTRINGCHARLEN = %d\n",
- MAXSTRINGCHARLEN);
- (void) printf ("\tMAXSTRINGCHARS = %d\n", MAXSTRINGCHARS);
- (void) printf ("\tMAX_CAPS = %d\n", MAX_CAPS);
- (void) printf ("\tMAX_HITS = %d\n", MAX_HITS);
- (void) printf ("\tMAX_SCREEN_SIZE = %d\n",
- MAX_SCREEN_SIZE);
- (void) printf ("\tMINCONTEXT = %d\n", MINCONTEXT);
- #ifdef MINIMENU
- (void) printf ("\tMINIMENU\n");
- #else /* MINIMENU */
- (void) printf ("\t!MINIMENU\n");
- #endif /* MINIMENU */
- (void) printf ("\tMINWORD = %d\n", MINWORD);
- (void) printf ("\tMSDOS_BINARY_OPEN = 0x%x\n",
- (unsigned int) MSDOS_BINARY_OPEN);
- (void) printf ("\tMSGLANG = %s\n", MSGLANG);
- #ifdef NO_CAPITALIZATION_SUPPORT
- (void) printf ("\tNO_CAPITALIZATION_SUPPORT\n");
- #else /* NO_CAPITALIZATION_SUPPORT */
- (void) printf ("\t!NO_CAPITALIZATION_SUPPORT\n");
- #endif /* NO_CAPITALIZATION_SUPPORT */
- #ifdef NO_STDLIB_H
- (void) printf ("\tNO_STDLIB_H\n");
- #else /* NO_STDLIB_H */
- (void) printf ("\t!NO_STDLIB_H (STDLIB_H)\n");
- #endif /* NO_STDLIB_H */
- #ifdef NO8BIT
- (void) printf ("\tNO8BIT\n");
- #else /* NO8BIT */
- (void) printf ("\t!NO8BIT (8BIT)\n");
- #endif /* NO8BIT */
- (void) printf ("\tNRSPECIAL = \"%s\"\n", NRSPECIAL);
- (void) printf ("\tOLDPAFF = \"%s\"\n", OLDPAFF);
- (void) printf ("\tOLDPDICT = \"%s\"\n", OLDPDICT);
- #ifdef PDICTHOME
- (void) printf ("\tPDICTHOME = \"%s\"\n", PDICTHOME);
- #else /* PDICTHOME */
- (void) printf ("\tPDICTHOME = (undefined)\n");
- #endif /* PDICTHOME */
- (void) printf ("\tPDICTVAR = \"%s\"\n", PDICTVAR);
- #ifdef PIECEMEAL_HASH_WRITES
- (void) printf ("\tPIECEMEAL_HASH_WRITES\n");
- #else /* PIECEMEAL_HASH_WRITES */
- (void) printf ("\t!PIECEMEAL_HASH_WRITES\n");
- #endif /* PIECEMEAL_HASH_WRITES */
- #if TERM_MODE != CBREAK
- (void) printf ("\tRAW\n");
- #endif /* TERM_MODE */
- #ifdef REGEX_LOOKUP
- (void) printf ("\tREGEX_LOOKUP\n");
- #else /* REGEX_LOOKUP */
- (void) printf ("\t!REGEX_LOOKUP\n");
- #endif /* REGEX_LOOKUP */
- (void) printf ("\tREGLIB = \"%s\"\n", REGLIB);
- (void) printf ("\tSIGNAL_TYPE = %s\n", SIGNAL_TYPE_STRING);
- (void) printf ("\tSORTPERSONAL = %d\n", SORTPERSONAL);
- (void) printf ("\tSTATSUFFIX = \"%s\"\n", STATSUFFIX);
- (void) printf ("\tTEMPNAME = \"%s\"\n", TEMPNAME);
- (void) printf ("\tTERMLIB = \"%s\"\n", TERMLIB);
- (void) printf ("\tTEXINFODIR = \"%s\"\n", TEXINFODIR);
- (void) printf ("\tTEXSPECIAL = \"%s\"\n", TEXSPECIAL);
- #ifdef TRUNCATEBAK
- (void) printf ("\tTRUNCATEBAK\n");
- #else /* TRUNCATEBAK */
- (void) printf ("\t!TRUNCATEBAK\n");
- #endif /* TRUNCATEBAK */
- #ifdef USESH
- (void) printf ("\tUSESH\n");
- #else /* USESH */
- (void) printf ("\t!USESH\n");
- #endif /* USESH */
- (void) printf ("\tWORDS = \"%s\"\n", WORDS);
- (void) printf ("\tYACC = \"%s\"\n", YACC);
- }
- #endif /* !AMIGA */
- exit (0);
- break;
- case 'n':
- if (arglen > 2)
- usage ();
- tflag = 0; /* nroff/troff mode */
- deftflag = 0;
- if (preftype == NULL)
- preftype = "nroff";
- break;
- case 't': /* TeX mode */
- if (arglen > 2)
- usage ();
- tflag = 1;
- deftflag = 1;
- if (preftype == NULL)
- preftype = "tex";
- break;
- case 'T': /* Set preferred file type */
- p = (*argv)+2;
- if (*p == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- p = *argv;
- }
- preftype = p;
- break;
- case 'A':
- if (arglen > 2)
- usage ();
- incfileflag = 1;
- aflag = 1;
- break;
- case 'a':
- if (arglen > 2)
- usage ();
- aflag++;
- break;
- #ifdef AMIGA
- case 'r': /* -r enables server mode */
- if (arglen > 2)
- usage ();
- rflag=1;
- break;
- #endif /* AMIGA */
- case 'D':
- if (arglen > 2)
- usage ();
- dumpflag++;
- nodictflag++;
- break;
- case 'e':
- if (arglen > 3)
- usage ();
- eflag = 1;
- if ((*argv)[2] == 'e')
- eflag = 2;
- else if ((*argv)[2] >= '1' && (*argv)[2] <= '4')
- eflag = (*argv)[2] - '0';
- else if ((*argv)[2] != '\0')
- usage ();
- nodictflag++;
- break;
- case 'c':
- if (arglen > 2)
- usage ();
- cflag++;
- lflag++;
- nodictflag++;
- break;
- case 'b':
- if (arglen > 2)
- usage ();
- xflag = 0; /* Keep a backup file */
- break;
- case 'x':
- if (arglen > 2)
- usage ();
- xflag = 1; /* Don't keep a backup file */
- break;
- case 'f':
- fflag++;
- p = (*argv)+2;
- if (*p == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- p = *argv;
- }
- askfilename = p;
- if (*askfilename == '\0')
- askfilename = NULL;
- break;
- case 'L':
- p = (*argv)+2;
- if (*p == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- p = *argv;
- }
- contextsize = atoi (p);
- break;
- case 'l':
- if (arglen > 2)
- usage ();
- lflag++;
- break;
- #ifndef USG
- case 's':
- if (arglen > 2)
- usage ();
- sflag++;
- break;
- #endif
- case 'S':
- if (arglen > 2)
- usage ();
- sortit = 0;
- break;
- case 'B': /* -B: report missing blanks */
- if (arglen > 2)
- usage ();
- compoundflag = COMPOUND_NEVER;
- break;
- case 'C': /* -C: compound words are acceptable */
- if (arglen > 2)
- usage ();
- compoundflag = COMPOUND_ANYTIME;
- break;
- case 'P': /* -P: don't gen non-dict poss's */
- if (arglen > 2)
- usage ();
- tryhardflag = 0;
- break;
- case 'm': /* -m: make all poss affix combos */
- if (arglen > 2)
- usage ();
- tryhardflag = 1;
- break;
- case 'N': /* -N: suppress minimenu */
- if (arglen > 2)
- usage ();
- minimenusize = 0;
- break;
- case 'M': /* -M: force minimenu */
- if (arglen > 2)
- usage ();
- minimenusize = 2;
- break;
- case 'p':
- cpd = (*argv)+2;
- if (*cpd == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- cpd = *argv;
- if (*cpd == '\0')
- cpd = NULL;
- }
- LibDict = NULL;
- break;
- case 'd':
- p = (*argv)+2;
- if (*p == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- p = *argv;
- }
- #ifdef AMIGA
- if ((index (p, '/') != NULL) || (index (p, ':') != NULL))
- #else
- if (index (p, '/') != NULL)
- #endif
- (void) strcpy (hashname, p);
- else
- (void) sprintf (hashname, "%s/%s", LIBDIR, p);
- if (cpd == NULL && *p != '\0')
- LibDict = p;
- p = rindex (p, '.');
- if (p != NULL && strcmp (p, HASHSUFFIX) == 0)
- *p = '\0'; /* Don't want ext. in LibDict */
- else
- (void) strcat (hashname, HASHSUFFIX);
- p = rindex (LibDict, '/');
- if (p != NULL)
- LibDict = p + 1;
- break;
- case 'V': /* Display 8-bit characters as M-xxx */
- if (arglen > 2)
- usage ();
- vflag = 1;
- break;
- case 'w':
- wchars = (*argv)+2;
- if (*wchars == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- wchars = *argv;
- }
- break;
- case 'W':
- if ((*argv)[2] == '\0')
- {
- argv++; argc--;
- if (argc == 0)
- usage ();
- minword = atoi (*argv);
- }
- else
- minword = atoi (*argv + 2);
- break;
- default:
- usage ();
- }
- argv++;
- argc--;
- }
-
- #ifdef AMIGA
- if (!argc && !lflag && !rflag && !aflag && !eflag && !dumpflag)
- #else
- if (!argc && !lflag && !aflag && !eflag && !dumpflag)
- #endif /* AMIGA */
- usage ();
-
- /*
- * Because of the high cost of reading the dictionary, we stat
- * the files specified first to see if they exist. If at least
- * one exists, we continue.
- */
- for (argno = 0; argno < argc; argno++)
- {
- if (access (argv[argno], 4) >= 0)
- break;
- }
- #ifdef AMIGA
- if (argno >= argc && !lflag && !rflag && !aflag && !eflag && !dumpflag)
- #else
- if (argno >= argc && !lflag && !aflag && !eflag && !dumpflag)
- #endif /* AMIGA */
- {
- (void) fprintf (stderr,
- argc == 1 ? ISPELL_C_NO_FILE : ISPELL_C_NO_FILES);
- exit (1);
- }
- if (linit () < 0)
- exit (1);
-
- if (preftype != NULL)
- {
- prefstringchar =
- findfiletype (preftype, 1, deftflag < 0 ? &deftflag : (int *) NULL);
- if (prefstringchar < 0
- && strcmp (preftype, "tex") != 0
- && strcmp (preftype, "nroff") != 0)
- {
- (void) fprintf (stderr, ISPELL_C_BAD_TYPE, preftype);
- exit (1);
- }
- }
- if (prefstringchar < 0)
- defdupchar = 0;
- else
- defdupchar = prefstringchar;
-
- if (compoundflag < 0)
- compoundflag = hashheader.compoundflag;
- if (tryhardflag < 0)
- tryhardflag = hashheader.defhardflag;
-
- initckch(wchars);
-
- if (LibDict == NULL)
- {
- (void) strcpy (libdictname, DEFHASH);
- LibDict = libdictname;
- p = rindex (libdictname, '.');
- if (p != NULL && strcmp (p, HASHSUFFIX) == 0)
- *p = '\0'; /* Don't want ext. in LibDict */
- }
- if (!nodictflag)
- treeinit (cpd, LibDict);
-
- #ifdef AMIGA
- if (rflag){ /* Enter server mode */
- servermode();
- exit(0);
- }
- #endif /* AMIGA */
-
- if (aflag)
- {
- askmode ();
- treeoutput ();
- exit (0);
- }
- else if (eflag)
- {
- expandmode (eflag);
- exit (0);
- }
- else if (dumpflag)
- {
- dumpmode ();
- exit (0);
- }
-
- #ifndef __bsdi__
- setbuf (stdout, outbuf);
- #endif /* __bsdi__ */
- if (lflag)
- {
- infile = stdin;
- outfile = stdout;
- checkfile ();
- exit (0);
- }
-
- terminit ();
-
- while (argc--)
- dofile (*argv++);
-
- done (0);
- /* NOTREACHED */
- return 0;
- }
-
- static void dofile (filename)
- char * filename;
- {
- struct stat statbuf;
- char * cp;
-
- currentfile = filename;
-
- /* See if the file is a .tex file. If so, set the appropriate flags. */
- tflag = deftflag;
- if (tflag < 0)
- tflag =
- (cp = rindex (filename, '.')) != NULL && strcmp (cp, ".tex") == 0;
-
- if (prefstringchar < 0)
- {
- defdupchar =
- findfiletype (filename, 0, deftflag < 0 ? &tflag : (int *) NULL);
- if (defdupchar < 0)
- defdupchar = 0;
- }
-
- if ((infile = fopen (filename, "r")) == NULL)
- {
- (void) fprintf (stderr, CANT_OPEN, filename);
- (void) sleep ((unsigned) 2);
- return;
- }
-
- readonly = access (filename, 2) < 0;
- if (readonly)
- {
- (void) fprintf (stderr, ISPELL_C_CANT_WRITE, filename);
- (void) sleep ((unsigned) 2);
- }
-
- (void) fstat (fileno (infile), &statbuf);
- (void) strcpy (tempfile, TEMPNAME);
- if (mktemp (tempfile) == NULL || tempfile[0] == '\0'
- || (outfile = fopen (tempfile, "w")) == NULL)
- {
- (void) fprintf (stderr, CANT_CREATE,
- (tempfile == NULL || tempfile[0] == '\0')
- ? "temporary file" : tempfile);
- (void) sleep ((unsigned) 2);
- return;
- }
- (void) chmod (tempfile, statbuf.st_mode);
-
- quit = 0;
- changes = 0;
-
- checkfile ();
-
- (void) fclose (infile);
- (void) fclose (outfile);
-
- if (!cflag)
- treeoutput ();
-
- if (changes && !readonly)
- update_file (filename, &statbuf);
- (void) unlink (tempfile);
- }
-
- static void update_file (filename, statbuf)
- char * filename;
- struct stat * statbuf;
- {
- char bakfile[MAXPATHLEN];
- int c;
- #ifdef TRUNCATEBAK
- int maxlen;
- #endif /* TRUNCATEBAK */
- char * pathtail;
-
- if ((infile = fopen (tempfile, "r")) == NULL)
- {
- (void) fprintf (stderr, ISPELL_C_TEMP_DISAPPEARED, tempfile);
- (void) sleep ((unsigned) 2);
- return;
- }
-
- #ifdef TRUNCATEBAK
- (void) strncpy (bakfile, filename, sizeof bakfile - 1);
- bakfile[sizeof bakfile - 1] = '\0';
- if (strcmp(BAKEXT, filename + strlen(filename) - sizeof BAKEXT - 1) != 0)
- {
- maxlen = MAXNAMLEN - strlen (BAKEXT);
- pathtail = rindex (bakfile, '/');
- if (pathtail == NULL)
- pathtail = bakfile;
- else
- pathtail++;
- if (strlen (pathtail) > MAXNAMLEN - sizeof BAKEXT - 1)
- pathtail[MAXNAMLEN - sizeof BAKEXT -1] = '\0';
- (void) strcat (pathtail, BAKEXT);
- }
- #else
- (void) sprintf (bakfile, "%.*s%s", (int) (sizeof bakfile - sizeof BAKEXT),
- filename, BAKEXT);
- #endif
-
- pathtail = rindex (bakfile, '/');
- if (pathtail == NULL)
- pathtail = bakfile;
- else
- pathtail++;
- if (strncmp (filename, bakfile, pathtail - bakfile + MAXNAMLEN) != 0)
- (void) unlink (bakfile); /* unlink so we can write a new one. */
- #ifdef HAS_RENAME
- (void) rename (filename, bakfile);
- #else /* HAS_RENAME */
- if (link (filename, bakfile) == 0)
- (void) unlink (filename);
- #endif /* HAS_RENAME */
-
- /* if we can't write new, preserve .bak regardless of xflag */
- if ((outfile = fopen (filename, "w")) == NULL)
- {
- (void) fprintf (stderr, CANT_CREATE, filename);
- (void) sleep ((unsigned) 2);
- return;
- }
-
- (void) chmod (filename, statbuf->st_mode);
-
- while ((c = getc (infile)) != EOF)
- (void) putc (c, outfile);
-
- (void) fclose (infile);
- (void) fclose (outfile);
-
- if (xflag
- && strncmp (filename, bakfile, pathtail - bakfile + MAXNAMLEN) != 0)
- (void) unlink (bakfile);
- }
-
- static void expandmode (option)
- int option; /* How to print: */
- /* 1 = expansions only */
- /* 2 = original line + expansions */
- /* 3 = original paired w/ expansions */
- /* 4 = add length ratio */
- {
- char buf[BUFSIZ];
- int explength; /* Total length of all expansions */
- register char * flagp; /* Pointer to next flag char */
- ichar_t ibuf[BUFSIZ];
- MASKTYPE mask[MASKSIZE];
- char origbuf[BUFSIZ]; /* Original contents of buf */
- char ratiobuf[20]; /* Expansion/root length ratio */
- int rootlength; /* Length of root word */
- register int temp;
-
- while (xgets (buf, sizeof buf, stdin) != NULL)
- {
- rootlength = strlen (buf);
- if (buf[rootlength - 1] == '\n')
- buf[--rootlength] = '\0';
- (void) strcpy (origbuf, buf);
- if ((flagp = index (buf, hashheader.flagmarker)) != NULL)
- {
- rootlength = flagp - buf;
- *flagp++ = '\0';
- }
- if (option == 2 || option == 3 || option == 4)
- (void) printf ("%s ", origbuf);
- if (flagp != NULL)
- {
- if (flagp - buf > INPUTWORDLEN)
- buf[INPUTWORDLEN] = '\0';
- }
- else
- {
- if ((int) strlen (buf) > INPUTWORDLEN - 1)
- buf[INPUTWORDLEN] = '\0';
- }
- (void) fputs (buf, stdout);
- if (flagp != NULL)
- {
- (void) bzero ((char *) mask, sizeof (mask));
- while (*flagp != '\0' && *flagp != '\n')
- {
- temp = CHARTOBIT ((unsigned char) *flagp);
- if (temp >= 0 && temp <= LARGESTFLAG)
- SETMASKBIT (mask, temp);
- else
- (void) fprintf (stderr, BAD_FLAG, (unsigned char) *flagp);
- flagp++;
- /* Accept old-format dicts with extra slashes */
- if (*flagp == hashheader.flagmarker)
- flagp++;
- }
- if (strtoichar (ibuf, buf, sizeof ibuf, 1))
- (void) fprintf (stderr, WORD_TOO_LONG (buf));
- explength = expand_pre (origbuf, ibuf, mask, option, "");
- explength += expand_suf (origbuf, ibuf, mask, 0, option, "");
- explength += rootlength;
- if (option == 4)
- {
- (void) sprintf (ratiobuf, " %f",
- (double) explength / (double) rootlength);
- (void) fputs (ratiobuf, stdout);
- (void) expand_pre (origbuf, ibuf, mask, 3, ratiobuf);
- (void) expand_suf (origbuf, ibuf, mask, 0, 3, ratiobuf);
- }
- }
- (void) putchar ('\n');
- }
- }
-